
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include "anytimer.h"
/*
 * 定义变量类型
 * */
struct job_node
{
    int sec;            //定时
    at_jobfunc_t func;  //功能函数
    void * arg;         //传参
    int pending;        //是否等待
    int completed;      //是否完成
    int pos;            //描述符
    pid_t pid;          //进程号
};

typedef void (*sighandler_t)(int);

/*
 * 定义变量
 * */
static struct job_node * jobs[JOB_MAX]; //任务数组
static int inited;                      //初始化标志位
static sighandler_t alrm_handler_save;  //最初动作保存
/*
 * 找空位小函数
 * */
static int get_free_pos()
{
    int i;
    for(i = 0; i < JOB_MAX; i++)
    {
        if(jobs[i] == NULL)
            return i;
    }
    return -1;
}
/*
 * 信号处理函数
 * */
static void alrm_handler(int s)
{

    int i = 0;
    pid_t pid;
    //定时
    alarm(1);
    //遍历任务数组
    for(i = 0; i < JOB_MAX; i++)
    {
        if(jobs[i] == NULL)
            continue;
        if(jobs[i]->pending == 1)   //等待中的任务秒数-1
        {
            jobs[i]->sec --;
            if(jobs[i]->sec == 0)   //若秒数为0，执行指定的函数
            {
                pid = fork();
                if(pid < 0)
                {
                    fprintf(stderr, "fork failed\n");
                    exit(1);
                }
                if(pid == 0)
                {
                    (jobs[i]->func)(jobs[i]->arg);  //调用函数
                    fflush(stdout);                 //清空缓冲区
                    jobs[i]->pending = 0;           //不再等待
                    jobs[i]->completed = 1;         //已经完成
                    exit(0);
                }
                if(pid > 0)
                {
                    jobs[i]->pid = pid;
                }
            }
        }
    }
}
/*
 * 加载模块函数
 * */
static void module_load(void)
{
    alarm(1);
    alrm_handler_save = signal(SIGALRM, alrm_handler);
}
/*
 * 添加任务函数
 * */
int at_addjob(int sec, at_jobfunc_t jobp, void * arg)
{
    int pos;
    //检验初始化标志位
    if(!inited)
    {
        module_load();
        inited = 1;
    }
    //申请空间存放任务节点
    struct job_node * node = malloc(sizeof(struct job_node));
    if(node == NULL)
        return -ENOMEM;
    //把任务节点的地址放在任务数组
    pos = get_free_pos();
    if(pos < 0)
        return -ENOSPC;
    //初始化任务信息
    node->sec = sec;        //定时
    node->func = jobp;      //功能函数
    node->arg = arg;        //传参
    node->pending = 1;      //正在等待
    node->completed = 0;    //还没完成
    node->pos = pos;        //描述符

    jobs[pos] = node;

    return pos;
}

int at_canceljob(int id)
{
    if(jobs[id] == NULL)
        return -EINVAL;
    if(jobs[id]->completed == 1)
        return -EBUSY;
    if(jobs[id]->pending == 0 && jobs[id]->completed == 0)
        return -ECANCELED;
    jobs[id]->pending = 0;
    return 0;
}

int at_waitjob(int id)
{
    if(jobs[id] == NULL)
        return -EINVAL;
    
}